home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Programming / Programming Languages / Yerk 3.64 / System source / Files < prev    next >
Text File  |  1993-06-17  |  14KB  |  488 lines

  1. \ Files  - file object and loader
  2. \ 09/10/84  CBD Version 1.0
  3. \ 10/12/84  CBD Added loader,  Length: -> bytesRead:
  4. \ 12/14/84  cbd nested loads, no default:
  5. \  7/04/86  cdn Added HFS references
  6. \  7/13/86  cdn Moved in SFPReply
  7. \  8/15/86  rfd Skip HFS search is vRefNum supplied
  8. \  8/26/86  cdn Added classinit for File
  9. \  9/8/86   rfd added dirfind resfind etc. to speed up open
  10. \ 12/3/87    rfl fixed pileup of pathnames in hopen
  11. \ 12/3/87   rfl addef flushvol:
  12. \  9/5/88    rfl    fixed hfs?
  13. \ 12/14/88    rfl fixing data record for hfs
  14. \  5/23/90    rfl added event processing during file loading
  15. \  7/25/90    rfl fixed load so that ?pause works during +echo
  16. \  9/27/90    rfl    savesig now finds app signature
  17. \ 11/12/90    rfl recoded volname?
  18. \ 12/14/90    rfl added font change to //
  19. \ 12/29/90    rfl    mods for path now sarray object
  20. \  1/31/91    rfl    fixed saveSig to get signature, not file name; font stuff now
  21. \                here; no longer need chicago 9.
  22. \  1/26/92    rfl    fixed Savesig to use heap file object. remove: loadfile closed the file.
  23. \                This wasn't good if the file was the standalone application.
  24. \ 11/25/92    rfl    Changed Last: to look at file size instead of using $ ffffff.
  25. \ 12/11/92    rfl    pulled ftype out of file, now global; added put: for single character write
  26. \                removed antiquated words like sony, external, profile; added where:
  27. \  4/30/93    rfl    Now when saving a snapshot of the environment, you no longer
  28. \                have to worry about closing the windows. The open windows are first marked
  29. \                closed, the file is saved, then they are all marked open again
  30. \  5/10/93    rfl    shortened filinit
  31. \  5/12/93    rfl    Hopen: and orf now lock down strings because of occasional problems
  32. \                 not building search path correctly due to moving of data
  33. \  5/17/93    rfl    removed res string call from clear: filelist so yerk.rsrc not
  34. \               necessary for string
  35. \  6/04/93    rfl    modified for source documentation; sfind and screate moved from 'mod'
  36. \  6/17/93    rfl    srcCreate now replaces a filemark with no yerk words defined after it.
  37.  
  38. Decimal
  39.  
  40. \ ( n fcb(abs) -- )
  41. Create dirfind
  42.     popA0
  43.     popD0
  44.     $ A260 w,
  45.     pushD0
  46.     next,
  47.  
  48. : volname? { strobj -- b }
  49.     start: strobj next: strobj
  50.     IF ascii : <> ELSE false THEN ;
  51.  
  52. 0 -> quitvec    \ leave vectors in a clean state
  53. 0 -> abortvec
  54.  
  55. : (nevent1) decho IF ?pause THEN ;
  56. 'c (nevent1) vect nEvent        \ use as stub until Event is loaded
  57.  
  58. : -echo  false -> decho ;
  59. : +echo  true  -> decho ;
  60. : -curs  false -> curs  ;
  61. : +curs  true  -> curs  ;
  62.  
  63. \ ( -- T or F ) returns true if on HFS
  64. : hfs? $ 3f6 -base w@ 0> ;
  65.  
  66. 0 value path    \ is instantiated by getPtxt
  67.  
  68. \  Strip volume name & HFS paths from a file name
  69. : MFSname { addr len -- addr' len' }
  70.     len ++> addr
  71.     len 0
  72.     DO    -1 ++> addr                \ scan through string backwards
  73.         addr c@ ascii : =        \ first colon we see, we stop
  74.         IF 1 ++> addr i -> len leave THEN
  75.     LOOP
  76.     addr len
  77. ;
  78.  
  79. : UpCase true -> ucase ;
  80. : LoCase false ->  ucase ;
  81.  
  82. \ ( addr len -- pfa len t OR f )  find word for name on stack. map to uppercase
  83. \   by default, but if ucase is false, then leave text alone.
  84. : sfind here >str255 ucase
  85.     IF 1+ here c@ >uc here ELSE -base THEN latest (find) ;
  86.  
  87. \ ( addr len -- )  create a new dict name/link for name on stack
  88. : sCreate docs IF line# w, THEN        \ for source documentation
  89.     sfind IF here count type type# 184 ( is redefined ) cr 2drop THEN
  90.     createHdr -4 allot ;
  91.  
  92. \ don't allow two adjacent words to be file marks...this will
  93. \ prevent a load file from being embedded in the dictionary...unless the
  94. \ loadfile begins by defining yerk words...thus a loadfile cannot do any
  95. \ defining for this to work all the time.
  96. : srcCreate ( addr len -- )            \ create a filemark entry to dictionary
  97.     docs
  98.     IF dup 31 > ?error 187
  99.         latest name> @ fileMk =        \ is the last word a filemark?
  100.         IF latest dup >line -> dp pfa lfa @ current ! THEN    \ yes, so get rid of it
  101.         LoCase
  102.         screate
  103.         fileMk , 
  104.         UpCase
  105.     ELSE 2drop
  106.     THEN ;
  107.  
  108.     4 Ordered-Col    fTypes        \ list of filetypes used by all files for stdget:
  109.  
  110. :CLASS File  <Super Object
  111.  
  112.     134 Bytes        FCB            \ max MAC parameter block(108 but for hgetvinfo)
  113.     \ Standard File data
  114.     Int                Good        \ this is like a variable record
  115.     Var                fType
  116.     Int                vRefNum
  117.     Int                Version
  118.     64 Bytes        Filename    \ max size is 64
  119.  
  120.     :M  CLOSE:  ^base (close)  ;M
  121.  
  122.     \ ( addr len -- )  assigns file name to fcb
  123.     :M  NAME:  ^base !fName  ;M
  124.  
  125.     \ ( dirid -- )  set the DirID for the fcb
  126.     :M  SETDIRID: ^base 48 + !  ;M
  127.  
  128.     \ ( -- dirid )  get the DirID for the fcb
  129.     :M  GETDIRID: ^base 48 + @  ;M
  130.  
  131.     \ ( vref# -- )  set the volRefNum for the fcb
  132.     :M  SETVREF:  ^base 22 + w! ;M
  133.  
  134.     \ ( -- vref# )  get the volRefNum for the fcb
  135.     :M  GETVREF:  ^base 22 + w@ ;M
  136.  
  137.     \ ( mode -- fCode )
  138.     :M  HOPEN: { mode \ fnam1 pathname rc -- }
  139.         path IF lock: path THEN
  140.         heap> String -> fnam1  new: fnam1
  141.         heap> String -> pathName new: pathName
  142.         addr: filename count put: fnam1
  143.         lock: fnam1
  144.         start: fnam1 path
  145.         IF  ascii : charOf: fnam1
  146.             IF drop ^base mode (open)    \ assumed to be qualified path name
  147.             ELSE
  148.                 limit: path 0
  149.                 DO i at: path put: pathname
  150.                     pathname volname? 0=  hfs? land
  151.                     IF    lock: pathname                                \ if not volume
  152.                         get: pathname name: self unlock: pathname    \ get dirid
  153.                         9 ^base +base dirfind drop
  154.                         getdirid: self
  155.                         get: fnam1 name: self
  156.                         setdirid: self
  157.                         ^base mode (open) -> rc    \ attempt to open
  158.                         rc 0= IF leave THEN        \ found it !!
  159.                     ELSE 
  160.                         pathName concat: fnam1
  161.                         lock: pathname get: pathname ^base !fName unlock: pathname
  162.                         ^base mode  (open)  -> rc
  163.                         rc 0= IF leave THEN        \ found it !!
  164.                     THEN
  165.                 LOOP
  166.                 rc IF get: fnam1 ^base !fName THEN
  167.                 rc    \ leave return code
  168.             THEN
  169.         ELSE
  170.             hfs? 0=        \ strip HFS paths under MFS
  171.             IF    ascii : charOf: fnam1
  172.                 IF    >R 0 -base                            \ setup for replace:
  173.                     get: fnam1 MFSname drop ptr: fnam1 R + -
  174.                     " :" drop R> 0> replace: fnam1        \ delete any path spec
  175.                     get: fnam1 addr: filename >str255 drop
  176.                 THEN
  177.             THEN
  178.             ^base mode (open)
  179.         THEN
  180.         release: fnam1 dispose> fnam1
  181.         release: pathname dispose> pathname
  182.         path IF unlock: path THEN
  183.     ;M
  184.  
  185.     \ ( -- fcode )  basic I/O operations
  186.     :M  OPEN:
  187.         ^base 22 + w@ ^base 48 + @ or
  188.         IF ^base 0 (open)
  189.         ELSE 0 Hopen: self THEN
  190.     ;M
  191.  
  192.     :M  NEW:    ^base  (make)  ;M
  193.     :M  DELETE: ^base (delete) ;M
  194.  
  195.     \ ( byteoffset -- fcode )  position relative to beginning-of-file
  196.     :M  MOVETO: ^base 1 rot (lseek)   ;M
  197.  
  198.     \ ( -- byteoffset ) current position relative to beginning-of-file
  199.     :M  WHERE: ^base 46 + @ ;M
  200.  
  201.     \ ( pos -- fcode )  set End-of-File to absolute byte position
  202.     :M  SETEOF: ^base 28 + !  ^base $ a012 (fdos) ;M
  203.  
  204.     \ ( -- fcode )  open and reset file or create new if not present
  205.     :M  CREATE: { \ volid -- fcode }
  206.         ^base 22 + w@ -> volid
  207.         open: self
  208.         -dup
  209.         IF    dup -43 =
  210.             volid ^base 22 + w!
  211.             IF    drop
  212.                 new: self -dup
  213.                 0= IF ^base 0 (open) THEN
  214.             THEN
  215.         ELSE
  216.             0 setEOF: self
  217.         THEN
  218.     ;M
  219.  
  220.     \ ( -- #bytes )  return logical eof for file currently open
  221.     :M  SIZE:  ^base $ a011 (fdos)  drop ^base 28 + @ ;M
  222.  
  223.     \ ( -- )  position to file's eof
  224.     :M  LAST:  size: self moveTo: self drop  ;M
  225.  
  226.     \ ( -- lengthRead )  return actual bytes read
  227.     :M  BYTESREAD:  ^base 40 + @ ;M
  228.  
  229.     \ ( -- fcbAddr )
  230.     :M  FCB:  ^base  ;M
  231.  
  232.     \ ( -- fcode )
  233.     :M  RESULT:  addr: fcb  16 + W@ ;M
  234.  
  235.     \ ( posMode -- )  Set position mode
  236.     :M  MODE:  ^base 44 + W!   ;M
  237.  
  238.     \ ( addr length -- fcode )
  239.     :M  READ: 0 mode: Self ^base swap rot (read)  ;M
  240.  
  241.     \ ( addr maxLen -- fcode )  Read terminating with CR
  242.     :M  READLINE:  $ 0d80 Mode: self ^base swap rot (read)  ;M
  243.  
  244.     \ ( addr length -- fcode )
  245.     :M  WRITE:  ^base  swap rot (write)  ;M
  246.  
  247.     \ ( n -- fcode )
  248.     :M  PUT: pad c! pad 1 write: self ;M
  249.  
  250.     \ ( -- )  Set Fcb fields to 0
  251.     :M  CLEAR:  ^base   clrFcb  ;M
  252.  
  253.     \ ( -- )  Get name from input stream, and assign to fcb
  254.     :M  SETNAME:  ^base setName ;M
  255.  
  256.     \ ( -- addr len )  return filename
  257.     :M  GETNAME:  addr: fileName count   ;M
  258.  
  259.     \ ( -- )  print the filename
  260.     :M  PRINT:  getName: self  type    ;M
  261.  
  262.     \ ( ftype sig -- )  Set file type, signature
  263.     :M  SET: { ftype sig -- }
  264.          getdirid: self  ^base  ftype sig  file-install  setdirid: self ;M
  265.  
  266.     \ ( drive# -- )  set default drive to drive#
  267.     :M  DRIVE:   Clear: self  setVRef: self  ^base $ a015 (fdos)
  268.         ?error 165   ;M    \ Drive change unsuccessful
  269.  
  270.     \ ( addr len -- eof )  Simulate a Yerk expect from disk
  271.     :M  EXPECT: { addr len -- }
  272.         addr len 1+ erase  addr len ReadLine: self  0=
  273.         IF  dEcho
  274.             IF  addr bytesRead: self  1+ type cr
  275.             THEN
  276.             addr bytesread: self + 1-  0 swap c!  0
  277.         ELSE  1 THEN   ;M
  278.  
  279.     \ ( -- eof )  Expect a line to the TIB
  280.     :M  QUERY:  0 -> in  Tib 128 Expect: self 1 ++> line# ;M
  281.  
  282.     \ interpret the file as a Yerk source file
  283.     \ ( -- )  name must first be set
  284.     :M  INTERPRET: { \ icurs -- } -1 -> line#
  285.         open: self  classErr" 132
  286.         getName: self
  287.         srcCreate            \ create file mark entry
  288.         curs -> icurs -curs    \ Preserve cursor status
  289.         BEGIN   nEvent
  290.                 query: self   0=
  291.         WHILE  Interpret State   0= dEcho   And
  292.             IF  ok  THEN
  293.         REPEAT  ?exec close: self drop
  294.         icurs -> curs -1 -> line#  ;M    \ Restore cursor status
  295.  
  296.      :M  FLUSHVOL: ^base $ A013 (fdos) drop ;M
  297.  
  298.     \ ( taddr tlen -- fcode )
  299.     :M  RENAME: { taddr tlen -- result }
  300.         taddr tlen str255
  301.         ^base 28 + !  ^base $ A00B (fdos) ;M
  302.  
  303.     \ ( -- fcode )
  304.     :M  OPENREADONLY:
  305.         ^base 22 + w@ ^base 48 + @ or
  306.         IF ^base 1 (open)
  307.         ELSE 1 Hopen: self THEN ;M
  308.  
  309.     \ ( -- type )
  310.     :M  GETTYPE:  ^base 32 + @ ;M
  311.  
  312.     \ ( -- fcode )  fills the parameter block with file info
  313.     :M  GETFILEINFO:  ^base $ A20C (fdos)  ;M
  314.  
  315.     \ ( routine# -- bool )  call a Standard File Package routine
  316.     :M  SFPCALL:  makeInt $ a9ea Trap
  317.         get: good
  318.         IF get: vRefNum ^base dup 80 erase set-file
  319.             setVref: self  True
  320.         ELSE  False
  321.         THEN     ;M
  322.  
  323.     \ ( type0 ...typeN #types -- bool )  call SFGetFile
  324.     :M  STDGET:  clear: fTypes  dup 0>
  325.         IF 0 DO add: fTypes LOOP
  326.         ELSE drop THEN
  327.         $ 640064 0 0  size: fTypes -dup 0= IF -1 THEN makeInt
  328.         ixAddr: fTypes +base 0 abs: good
  329.         2 sfpCall: self  ;M
  330.  
  331.     \ call SFPutFile - takes promp, origName strings
  332.     :M  STDPUT:  { pAddr pLen nAddr nLen -- bool }
  333.         pLen pad c! pAddr pad 1+ pLen cmove
  334.         $ 640064  pad +base  nAddr nLen str255 0 abs: good
  335.         1 sfpCall: self  ;M
  336.  
  337.     :M  CLASSINIT:  clear: self  ;M
  338.  
  339. ;CLASS
  340.  
  341. ' File 'c fFcb !        \ set ffcb to member of file class
  342.  
  343. \ FileList keeps a stack of open load files for nested loads.
  344. :CLASS FileList  <Super Ordered-Col
  345.  
  346.     \ release heap for the top element
  347.     :M  REMOVE:  get: size dup 0= classerr" 137
  348.         1- ^elem close: [ dup @ ] drop
  349.         dispose  -1 +: size  ;M
  350.  
  351.     \ ( -- ^file ) add a new file to the stack
  352.     :M  NEW:  heap> file  add: super   ;M
  353.  
  354.     \ interpret the top file
  355.     :M  INTERPRET:  interpret: [ last: self ]  ;M
  356.  
  357.     \ ( -- )  remove all currently open files
  358.     :M  CLEAR:  ." File stack: " cr \ type# 180 ( File stack: ) cr
  359.         get: size 0
  360.         DO print: [ last: self ] cr remove: self
  361.         LOOP  ;M
  362.  
  363.     \ ( -- )  initialize list at startup
  364.     :M  INIT:   clear: super  ;M
  365.  
  366. ;CLASS
  367.  
  368. 6 fileList loadFile
  369.  
  370. : lastLoad  last: loadFile ;
  371. 'c lastLoad vect topFile
  372.  
  373. \ ( addr len -- )  open named resource file
  374. : orf { \ fnam1 pathname RC nfcb -- }
  375.     new: loadFile name: topFile
  376.     word0 getname: topfile str255 $ a997 trap i->l -1
  377.      = IF
  378.        HFS?  path land IF
  379.         HEAP> String -> fnam1 new: fnam1
  380.         heap> string -> pathName new: pathName
  381.         getname: topfile put: fnam1 lock: fnam1
  382.         -1 -> RC
  383.         HEAP> file -> nfcb
  384.         limit: path 0 DO
  385.             i at: path put: pathname
  386.             start: fnam1 get: fnam1 add: pathname
  387.             lock: pathname get: pathname
  388.             name: nfcb 9 nfcb +base dirfind
  389.             0= IF nfcb 30 + c@ 16 and ELSE true Then  not
  390.             IF
  391.                 word0 get: pathname STR255
  392.                 $ a997 trap i->l -> RC
  393.                 LEAVE
  394.             THEN unlock: pathname
  395.         LOOP
  396.         Dispose> nfcb
  397.         release: pathname dispose> pathname
  398.         release: fnam1 dispose> fnam1
  399.     ELSE   word0 getname: topfile STR255 $ a997 trap i->l -> rc
  400.     THEN     RC -1 = abort" resource file open failed"
  401.   THEN   remove: loadfile
  402. ;
  403. \ ( addr len - )
  404. :F OpenResFile ORF ;F
  405.  
  406. \ used to be defined in Event
  407. \ ( val -- )  set text characteristics for current grafPort
  408. : tfont  makeint $ a887 trap ;
  409. : tFace  makeInt $ a888 trap ;
  410. : tMode  makeInt $ a889 trap ;
  411. : tSize  makeInt $ a88a trap ;
  412.  
  413. \ nesting loader. Use: // filename
  414. : // { \ lcurs -- }
  415.     curs -> lcurs -curs    \ Preserve cursor status
  416.     new: loadFile  setName: topFile
  417.     getName: topFile  3 tfont 1 tface type# 173 ( Loading: ) type 0 tface 4 tfont cr
  418.     interpret: topFile  remove: loadFile
  419.     lcurs -> curs ;        \ Restore cursor status
  420.  
  421. \ ================ Save ====================
  422.  
  423. 'type COM  CONSTANT saveType            \ file type = 'COM '
  424. \ use current application signature
  425. : saveSig { \ myFile -- }
  426.     heap> file -> myFile                \ need a file structure
  427.     $ 910 -base count name: myFile        \ get nucleus name
  428.     getFileInfo: myFile drop            \ get info
  429.     myFile 36 + @ dispose> myFile ;        \ get signature
  430.  
  431. ( -- Length of dictionary to be saved )
  432. : flen      here Begin-dp @  - ;
  433.  
  434. Forward purge    \ defined in Ovl
  435.  
  436. 0 Variable  H1 here 16 allot 16 erase
  437.  
  438. \ mark all windows closed
  439. : togWindows { flag \ theWindow -- } 0 $ a924 trap
  440.     BEGIN -base -> theWindow
  441.           theWindow $ 90 + @                \ get next window in list
  442.            flag theWindow 184 + w! ( markClosed: theWindow ) dup 0=    \ continue until no more windows
  443.     UNTIL drop ;
  444. : markWindowsClosed 0 togWindows ;
  445. : markWindowsOpen   1 togWindows ;
  446.  
  447. \ Reuse target BIN file- so as not to wrestle file from it's folde
  448. \ ( -- )  Save the user dictionary
  449. : (Save) markWindowsClosed
  450.     purge
  451.     path 0 -> path    \ temporarily zero out path
  452.     fFcb set-file
  453.     create: fFcb ?error 107
  454.     \ SAVE-HEAD
  455.         here H1 !            \ Save DP
  456.         fence H1 4+ !        \ Save FENCE
  457.         voc-link H1 8+ !    \ Save VOC-LINK
  458.         latest H1 12 + !    \ Save latest NFA
  459.         0 mode: fFcb  0 fFcb 46 + w!
  460.         H1 16 write: fFcb ?error 101
  461.     \ WRITE-DICT
  462.         $ 10 fFcb $ 2E + W!
  463.         begin-dp @ flen write: fFcb ?error 105
  464.     saveType saveSig set: fFcb
  465.     close: fFcb drop
  466.     -> path            \ restore path
  467.     markWindowsOpen ;
  468.  
  469. \ Save command takes name from input stream
  470. : Save
  471.     setName: fFcb (save) ;
  472.  
  473. \ when // executes, it adds a new file object on the heap to a
  474. \ stack of files. This permits embedded loads, providing hierarchical
  475. \ nesting of source files.
  476.  
  477. : cleanUp  [Compile] ;class  clear: loadFile  init8  parmlist -1 -> line# ;
  478. : filinit   ' File 'c fFcb !  init: loadFile ;
  479.  
  480. 'c filinit -> objinit
  481. 'c cleanUp -> abortvec
  482.  
  483. 'type TEXT constant txType
  484.  
  485. \ true -> docs
  486.  
  487. // tool.load
  488.